#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "aimage.h"
#include "aimage_utils.h"
#include "accumulate.h"
#include "aimage_dcraw.h"
#include "aimage_ppm.h"

int main( int argc, const char *argv[] )
{
	char buffer[ 256 ];
	char base[ 256 ];
	FILE *stack_input;
	FILE *flat;
	ACCUMULATOR image;
	ACCUMULATOR std_image;
	ACCUMULATOR timage;
	int width, height;
	AIMAGE hotmap;
	AIMAGE darkframe;
	AIMAGE frame;
	AIMAGE flatframe;
	AIMAGE inv_adjust;
	bool has_flat = false;

	if ( argc != 2 )
	{
		fprintf(stderr, "%s stack_file.txt\n", argv[0] );
		exit( 1 );
	}

	fprintf(stderr, "reading hotmap\n");
	AIMAGE_PPM_UTILS::load( hotmap, "hotmap.ppm" );
	fprintf(stderr, "reading darkframe\n");
	AIMAGE_PPM_UTILS::load( darkframe, "dark.ppm" );

	flat = fopen( "flat.ppm", "rb" );
	if ( flat )
	{
		fclose( flat );	
		AIMAGE_PPM_UTILS::load( flatframe, "flat.ppm" );
		has_flat = true;
		int flat_width, flat_height;
		flatframe.get_dim( flat_width, flat_height );
		
		inv_adjust.alloc_image( flat_width, flat_height );
		AIU::make_flat_invadjust( inv_adjust, flatframe );
		AIU::correct_for_flatframe( darkframe, inv_adjust );
	}

	stack_input = fopen( argv[ 1 ], "rt" );
	if ( stack_input == NULL )
	{
		fprintf( stderr, "%s Unable to open %s\n", argv[0], argv[1] );
	}

	assert ( fgets( buffer, 256, stack_input ) != NULL );
	sscanf( buffer, "%s", base );

	fprintf(stderr, "reading base %s\n", base);
	AIMAGE_DCRAW_UTILS::load( frame, base );
	frame.get_dim( width, height );
	image.alloc_image( width, height );
	timage.alloc_image( width, height );

	int count = 0;

	fprintf(stderr, "Pass 1 - Computing Averages\n");
	while ( fgets( buffer, 256, stack_input ) != NULL )
	{
		float score;
		char file_name[ 256 ];
		float ratio;
		float score2;
		float distance;
		float orig_to_frame_angle;
		float orig_to_frame_x;
		float orig_to_frame_y;

		sscanf(buffer, "Score %9f File %s Ratio %g Score %g Distance %9f Angle %g XTrans %g YTrans %g\n",
			&score,
			file_name,
			&ratio,
			&score2,
			&distance,
			&orig_to_frame_angle,
			&orig_to_frame_x,
			&orig_to_frame_y );

		//orig_to_frame_x /= 2;
		//orig_to_frame_y /= 2;

		fprintf(stderr, "File %s angle %g x %g y %g\n",
			file_name, orig_to_frame_angle, orig_to_frame_x, orig_to_frame_y );

		float frame_to_orig_angle;
		float frame_to_orig_x;
		float frame_to_orig_y;

		frame_to_orig_angle = -orig_to_frame_angle;	// inverse
		frame_to_orig_x = 
				cosf( frame_to_orig_angle ) * -orig_to_frame_x -
				sinf( frame_to_orig_angle ) * -orig_to_frame_y;
		frame_to_orig_y = 
				sinf( frame_to_orig_angle ) * -orig_to_frame_x +
				cosf( frame_to_orig_angle ) * -orig_to_frame_y;

		ASTAR_TRANSFORM t;
		t.xo = frame_to_orig_x;
		t.yo = frame_to_orig_y;
		t.angle = frame_to_orig_angle;

		AIMAGE_DCRAW_UTILS::load( frame, file_name );
		AIU::correct_for_hotmap( frame, hotmap );
		AIU::correct_for_flatframe( frame, inv_adjust );
		image.rotate_and_add( frame, t );
		image.rotate_and_sub_dark( darkframe, t );
		//image.rotate_and_sub_dark( flatframe, t );
	}

	fprintf(stderr,"Converting accumulation back to image\n");
	image.to_image( frame );
	fprintf(stderr,"Writing image is stacked_image.ppm\n");
	AIMAGE_PPM_UTILS::save( frame, "stacked_image.ppm", true );

#ifdef FIXME
	image.normalize(); 

	fprintf(stderr, "Pass 2 - Computing Standard Deviations\n");
	while ( fgets( buffer, 256, stack_input ) != NULL )
	{
		float score;
		char file_name[ 256 ];
		float ratio;
		float score2;
		float distance;
		float orig_to_frame_angle;
		float orig_to_frame_x;
		float orig_to_frame_y;

		sscanf(buffer, "Score %9f File %s Ratio %g Score %g Distance %9f Angle %g XTrans %g YTrans %g\n",
			&score,
			file_name,
			&ratio,
			&score2,
			&distance,
			&orig_to_frame_angle,
			&orig_to_frame_x,
			&orig_to_frame_y );

		fprintf(stderr, "File %s angle %g x %g y %g\n",
			file_name, orig_to_frame_angle, orig_to_frame_x, orig_to_frame_y );

		float frame_to_orig_angle;
		float frame_to_orig_x;
		float frame_to_orig_y;

		frame_to_orig_angle = -orig_to_frame_angle;	// inverse
		frame_to_orig_x = 
				cosf( frame_to_orig_angle ) * -orig_to_frame_x -
				sinf( frame_to_orig_angle ) * -orig_to_frame_y;
		frame_to_orig_y = 
				sinf( frame_to_orig_angle ) * -orig_to_frame_x +
				cosf( frame_to_orig_angle ) * -orig_to_frame_y;

		ASTAR_TRANSFORM t;
		t.xo = frame_to_orig_x;
		t.yo = frame_to_orig_y;
		t.angle = frame_to_orig_angle;

		ASTAR_TRANSFORM to;
		to.xo = 0;
		to.yo = 0;
		to.angle = 0;

		AIMAGE_DCRAW_UTILS::load( frame, file_name );
		AIU::correct_for_hotmap( frame, hotmap );
		timage.cls();
		timage.rotate_and_add( frame, t );
		timage.rotate_and_sub_dark( darkframe, t );
		//timage.rotate_and_sub_dark( image, to );



		if ( 0 ) {
			fprintf(stderr, "Test aligning\n");
			char buffer[256]; 	
			timage.cls();
			timage.rotate_and_add( frame, t ); 	
			timage.to_image( frame );
			sprintf( buffer, "sample_%d.ppm", count);
			AIMAGE_PPM_UTILS::save( frame, buffer, true );
			count++;
			fprintf(stderr, "Done test aligning\n");
		}
	}
#endif

}

